export class Watcher {
  constructor(vm, expOrFn, cb, options) {
    this.vm = vm;
    this.expOrFn = expOrFn; // 传入的计算属性或表达式
    this.cb = cb; // 数据变化后要执行的回调函数
    if (options) {
        this.lazy = !!options.lazy; // 标记是否是懒执行的（主要用于 computed）
    }
    this.dirty = this.lazy; // computed 属性是否需要重新计算
    this.deps = []; // 存放依赖项
    this.set = {}; // 去重机制，避免重复依赖
    this.id = id++; // 每个 Watcher 的唯一标识
    if (typeof expOrFn === 'function') {
        this.getters = expOrFn; // 如果 expOrFn 是函数，将其赋给 getters
    }
    // 留住初始的 value 值
    this.value = this.lazy ? undefined : this.get();
  }

  get() {
    // 标记当前的 Watcher 为 全局Dep.target，收集依赖
    pushTarget(this);
    // 调用计算属性的 getter 方法，获取最新值
    let value = this.getters.call(this.vm, this.vm);
    // 重置 Dep.target 避免不必要的依赖
    popTarget();
    return value;
  }

  run() {
    // computed的方法
    let newValue = this.get();
    // 这里通常会调用 this.cb(newValue, oldValue) 来执行回调
  }

  addDep(dep) {
      let id = dep.id
      //去重防止dep添加watch多次
      if (!this.set[id]) {
          //watcher添加dep
          this.deps.push(dep)
          //给dep添加watch
          dep.addSub(this)
          this.set[id] = true;
      }
  }
  upDate() {
    //修改属性计算属性依赖的变量重置 dirty 
      if (this.lazy) {
          this.dirty = true
      }
  }
  evaluate() {
    //当走到这里时，页面正在渲染中 Dep.target 已经有一个渲染 watcher 了
      this.value = this.get();
      //修改了计算属性里面脏值
      this.dirty = false
  }
  depend () {
    //给 computed 函数内部的属性添加渲染 watcher
      let i = this.deps.length
      while (i--) {
          this.deps[i].depend()
      }
  }
}